package com.leapcloud.crm.core.utils;

import lombok.extern.slf4j.Slf4j;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

/**
 * @author wangzhenyan
 * @email ffu@maxleap.com
 * @since 2018/8/30 14:45
 */
@Slf4j
public class DateTimeUtils {

  public static final String FOTAMT_YYYYMMDDHHMMSS = "yyyy-MM-dd HH:mm:ss";

  public static final String FOTAMT_YYYYMMDDHHMM = "yyyy-MM-dd HH:mm";

  public static final String FOTAMT_YYYYMMDDHH = "yyyy-MM-dd HH";

  public static final String FOTAMT_YYYYMMDD = "yyyy-MM-dd";

  public static final String FOTAMT_YYYYMMDD1 = "yyyyMMdd";

  public static final String FORMAT_YYYYMM = "yyyyMM";


  public static String longToString(long timestamp) {
    return longToString(timestamp, FOTAMT_YYYYMMDDHHMMSS);
  }

  public static String longToString(long timestamp, String format) {
    if (timestamp == 0l) {
      return "";
    }
    return new SimpleDateFormat(format).format(new Date(timestamp));
  }

  public static Long toLong(String time, String format) {
    try {
      return new SimpleDateFormat(format).parse(time).getTime();
    } catch (ParseException e) {
      log.error("toLong error={}", e.getMessage(), e);
      return 0L;
    }
  }


  public static Long toLong(LocalDate localDate) {
    Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
    return date.getTime();
  }

  public static Long toNextMonth(String time, String format) {
    long current = toLong(time, format);
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(current);
    calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + 1);
    return calendar.getTimeInMillis();
  }

  public static Long toNextMonth(long current) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(current);
    calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + 1);
    return calendar.getTimeInMillis();
  }

  public static Long toPrevMonth(long current) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(current);
    calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1);
    return calendar.getTimeInMillis();
  }

  public static String toPrevMonthString(long current) {
    return longToString(toPrevMonth(current),FORMAT_YYYYMM);
  }

  public static Timestamp toTimestamp(Date date) {
    return new Timestamp(date.getTime());
  }

  public static Timestamp toTimestamp(long timestamp) {
    return new Timestamp(timestamp);
  }

  public static LocalDateTime getDateTimeFromTimestamp(long timestamp) {
    if (timestamp == 0)
      return null;
    return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), TimeZone
        .getDefault().toZoneId());
  }

  public static LocalDate getDateFromTimestamp(long timestamp) {
    LocalDateTime date = getDateTimeFromTimestamp(timestamp);
    return date == null ? null : date.toLocalDate();
  }

  public static int getDiffMonths(long start,long end) {
    if (start == end) {
      return 0;
    }
    if (start > end) {
      long temp = start;
      start = end;
      end = temp;
    }
    Calendar calendar1 = Calendar.getInstance();
    Calendar calendar2 = Calendar.getInstance();
    calendar1.setTime(new Date(start));
    calendar2.setTime(new Date(end));
    return (calendar2.get(Calendar.YEAR) - calendar1.get(Calendar.YEAR)) * 12 + calendar2.get(Calendar.MONTH) - calendar1.get(Calendar.MONTH);
  }

  public static long toFixInternalDay(long time, int day) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(time);
    calendar.add(Calendar.DAY_OF_MONTH, day);
    return calendar.getTimeInMillis();
  }

  public static long getStartTimeOfDay(long now) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(now);
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    return calendar.getTimeInMillis();
  }

}
